package com.cngphone.AnFetion;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;

public class FetionSIPC {
	private static final long serialVersionUID = -4506652254737369834L;

	public ArrayList<HeaderPair> getHeaders() {
		return headers;
	}

	public FetionSIPC response;
	public static final String FETION_PROTOCOL = "SIP-C/2.0";
	public static final String FETION_DOMAIN = "fetion.com.cn";

	public void SetResponse(FetionSIPC response) {
		this.response = response;
	}

	public String cmdLine;

	public String getCmdLine() {
		return cmdLine;
	}

	public boolean isResponse() {
		return this.getCmdLine().startsWith(FETION_PROTOCOL)
				&& this.getCmdLine().length() >= FETION_PROTOCOL.length() + 4;
	}

	public boolean isRequest() {
		return !(this.getCmdLine().startsWith(FETION_PROTOCOL) && this
				.getCmdLine().length() >= FETION_PROTOCOL.length() + 4);
	}

	public ArrayList<HeaderPair> headers;
	public String body;

	public class RequestCmdLine {
		public String cmd;
		public String domain;
		public String protocol;

		public RequestCmdLine(String cmd, String domain, String protocol) {
			this.cmd = cmd;
			this.domain = domain;
			this.protocol = protocol;
		}

		public RequestCmdLine(String cmdLine) throws Exception {
			int pos = cmdLine.indexOf(" ");
			if (pos <= 0 || pos >= cmdLine.length() - 1)
				throw new Exception();
			this.cmd = cmdLine.substring(0, pos);
			int lastpos = pos;
			pos = cmdLine.indexOf(" ", lastpos + 1);
			if (pos <= 0 || pos >= cmdLine.length() - 1)
				throw new Exception();
			this.domain = cmdLine.substring(lastpos + 1, pos);
			this.protocol = cmdLine.substring(pos + 1);
		}
	}

	public class ResponseCmdLine {
		public String protocol;
		public String code;
		public String description;

		public ResponseCmdLine(String protocol, String code, String description) {
			this.protocol = protocol;
			this.code = code;
			this.description = description;
		}

		public ResponseCmdLine(String cmdLine) throws Exception {
			int pos = cmdLine.indexOf(" ");
			if (pos <= 0 || pos >= cmdLine.length() - 1)
				throw new Exception();
			this.protocol = cmdLine.substring(0, pos);
			int lastpos = pos;
			pos = cmdLine.indexOf(" ", lastpos + 1);
			if (pos <= 0 || pos >= cmdLine.length() - 1)
				throw new Exception();
			this.code = cmdLine.substring(lastpos + 1, pos);
			this.description = cmdLine.substring(pos + 1);
		}
	}

	public FetionSIPC(String cmdLine, ArrayList<HeaderPair> headers, String body) {
		this.cmdLine = cmdLine;
		this.headers = headers;
		this.body = body;
	}

	/**
	 * 获取Q参数的值，即序列号.
	 * 
	 * @throws Exception
	 */
	public String GetQ() throws Exception {
		return GetHeaderValue("Q");
	}

	public String GetHeaderValue(String name) throws Exception {
		return GetHeaderValue(name, this.headers);
	}

	public static String GetHeaderValue(String name,
			ArrayList<HeaderPair> headerlists) throws Exception {
		for (int i = headerlists.size() - 1; i >= 0; i--) {
			if (headerlists.size() > i
					&& headerlists.get(i).name.trim().equals(name)) {
				return headerlists.get(i).value.trim();
			}
		}
		throw new Exception();
	}

	public RequestCmdLine getRequestCmdLine() throws Exception {
		return new RequestCmdLine(this.cmdLine);
	}

	public ResponseCmdLine getResponseCmdLine() throws Exception {
		return new ResponseCmdLine(this.cmdLine);
	}

	@Override
	public String toString() {
		/* 
		 * you can not modify the str content (blank-space 
		 * will be ignored) 
		 * bangbang.song@gmail.com 20091107
		 */
		String str = this.cmdLine;
		for (int i = 0; i < headers.size(); i++)
			str += "\r\n" + headers.get(i).name + ": " + headers.get(i).value;
		str += "\r\n\r\n";
		if (this.body != null)
			str += this.body;
		return str;
	}

	public static FetionSIPC parse(String str) {
		ByteArrayInputStream stream = new ByteArrayInputStream(str.getBytes());
		FetionReader reader = new FetionReader(stream);
		try {
			return reader.ReadSIPCPackage();
		} finally {
			try {
				reader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static class HeaderPair {
		public String name;
		public String value;

		public HeaderPair(String name, String value) {
			this.name = name;
			this.value = value;
		}

		public static HeaderPair Parse(String nvstr) throws Exception {
			int pos = nvstr.indexOf(":");
			if (pos == 0)
				throw new Exception("");
			return new HeaderPair(nvstr.substring(0, pos), nvstr
					.substring(pos + 1));
		}

		@Override
		public String toString() {
			return name + ": " + value;
		}

	}
}
